﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Models;
using System.Net.Sockets;
using System.Windows.Forms;
using System.Threading;
using MySocketHelper;

namespace BLL
{    
    public class AGVCommunicationManager
    {
        private List<byte> buffer = new List<byte>(4096);//默认分配1页内存，并始终限制不允许超过   
        private byte[] binary_data_1 = new byte[16];//AA 44 05 01 02 03 04 05 EA 
        private bool Listening = false;
        string[] CN_AGVStatus = new string[] { "失联","复位","运行","机械防撞","红外防撞","定时停","急停","出轨","错误","交管状态","前向运行","后向运行",
                                                               "前出轨","后出轨","减速运行","充电中","左拐","右拐","待命中","换前向停","换后向停","换反向停","站点待命",
                                                                "左横移","右横移","逆时针旋转","顺时针旋转","对接中","对接完成","对接失败","对接超时"};
        string[] JP_AGVStatus = new string[] { "連係を失う","リセット","実行する","機械的な衝突","赤外線対策","タイミングが止まる","急に止まる","脱線する","誤り","パイプの状態","前に運行する","後に実行する",
                                                               "前から脱線する","後から脱線する","減速運転","充電中","左に曲がる","右を曲がる","待機中","前へかえる","取り替える","逆回転する","サイトの待機",
                                                                "左横に移動する","右へ移動する","逆時計回転","時計回りに回転する","対接中","接戦完了","接戦に失敗する","接戦時"};
        string[] AGVStatus = new string[]{};
        private int languageid = Common.LanguageSetting.GetCurrentLanguageId();
        #region 协议解析
        /// <summary>
        /// 调度系统协议解析
        /// </summary>
        /// <param name="data">接收数据</param>
        /// <param name="ip">接收数据的IP地址</param>
        /// <returns>AGV状态信息</returns>
        public AGVInfo ResolutionProtocol(byte[] data, AGVInfo objPreAGV)
        {
            //AGVInfo objAGVInfo = new AGVInfo()
            //{
            //    IP = objPreAGV.IP
              
            //};//定义获取AGV信息的实体类
            AGVInfo objAGVInfo = null;
            //<协议解析>   
            bool data_1_catched = false;//缓存记录数据是否捕获到   
            //1.缓存数据   
            // buffer.AddRange(data);
            if (Listening == false)
            {
                //2.完整性判断   
                while (data.Length >= 16)//至少要包含头（2字节）+校验（1字节）   
                {
                    //2.1 查找数据头 + 数据尾  
                    if (data[0] == 0xAB && data[13] == 0xCD)
                    {
                        //2.2 探测缓存数据是否有一条数据的字节，如果不够，就不用费劲的做其他验证了   
                        //前面已经限定了剩余长度>=4，那我们这里一定能访问到buffer[2]这个长度  
                        int len = 16;//数据长度   
                        //数据完整判断第一步，长度是否足够   
                        //len是数据段长度,4个字节是while行注释的3部分长度   
                        // if (buffer.Count < len) break;//数据不够的时候什么都不做   
                        //这里确保数据长度足够，数据头标志找到，我们开始计算校验   
                        //2.3 校验数据，确认数据正确   
                        //异或校验，逐个字节异或得到校验码 

                        //byte checksum = 0;
                        //int sum = 0;
                        //for (int i = 0; i < 12; i++)//len+3表示校验之前的位置   
                        //{
                        //    sum += buffer[i];
                        //}
                        //checksum = (byte)(sum % 256);
                        //if (checksum != buffer[12]) //如果数据校验失败，丢弃这一包数据   
                        //{
                        //    buffer.RemoveRange(0, len);//从缓存中删除错误数据   
                        //    continue;//继续下一次循环   
                        //}
                        //至此，已经被找到了一条完整数据。我们将数据直接分析，或是缓存起来一起分析   
                        //我们这里采用的办法是缓存一次，好处就是如果你某种原因，数据堆积在缓存buffer中   
                        //已经很多了，那你需要循环的找到最后一组，只分析最新数据，过往数据你已经处理不及时   
                        //了，就不要浪费更多时间了，这也是考虑到系统负载能够降低。   
                        //buffer.CopyTo(0, binary_data_1, 0, len);//复制一条完整数据到具体的数据缓存   
                        data_1_catched = true;
                        // buffer.RemoveRange(0, len);//正确分析一条数据，从缓存中移除数据。   
                    }
                    else
                    {
                        //这里是很重要的，如果数据开始不是头，则删除数据   
                        // buffer.RemoveAt(0);
                        //buffer.RemoveRange(0, 16);//正确分析一条数据，从缓存中移除数据。
                        //objAGVInfo = null; //数据解析不正确
                        break;
                    }
                    // }
                    //分析数据   
                    if (data_1_catched)
                    {
                        Listening = true;
                        data_1_catched = false;
                        //</协议解析>   
                        ///////////////////////////////////////////////////////////////////////////////////////////////////////////// 
                        switch (data[2])
                        {
                            case 0x05:
                               objAGVInfo = new AGVInfo()
                                {
                                    IP = objPreAGV.IP, //IP地址
                                    PreLandNum = (data[3] << 8) + data[4], //当前地标号
                                    AimStation = data[5],//目标站点
                                    Speed = data[6],//当前速度
                                    PreAGVStatus = AGVStatus[data[7]],//当前AGV状态
                                    LiftStatus = data[8] == 0x0a ? "挂钩升" : "挂钩降", //挂钩状态
                                    Electricity = (double)data[9] + (double)(data[10]) / 100,//电量
                                    UpdateTime = DateTime.Now,//更新时间
                                    AGVName = objPreAGV.AGVName,
                                    //TrackId = objPreAGV.TrackId,
                                    TrackName = objPreAGV.TrackName,
                                    OnLineStatus = objPreAGV.OnLineStatus
                                };
                                //根据地标号实现其他功能
                                break;
                            default:
                                objAGVInfo = null;
                                break;
                        }
                        Listening = false;
                        break;
                    }
                    else objAGVInfo = null;
                }
            }
            return objAGVInfo;
            // builder.Clear();//清除字符串构造器的内容   
        }
    #endregion

        //#region 协议解析2
        ///// <summary>
        ///// 调度系统协议解析
        ///// </summary>
        ///// <param name="data">接收数据</param>
        ///// <param name="ip">接收数据的IP地址</param>
        ///// <returns>AGV状态信息</returns>
        //public AGVInfo ResolutionProtocol2(AsyncUserToken token,byte[] data )
        //{

        //    AGVInfo objAGVInfo = null;
        //    //<协议解析>   
        //    bool data_1_catched = false;//缓存记录数据是否捕获到   
        //    //1.缓存数据   
        //    token.Buffer.AddRange(data);
        //    //if (Listening == false)
        //    //{
        //        //2.完整性判断   
        //        while (token.Buffer.Count >= 16)//至少要包含头（2字节）+校验（1字节）   
        //        {
        //            //2.1 查找数据头 + 数据尾  
        //            if (token.Buffer[0] == 0xAB && token.Buffer[13] == 0xCD)
        //            {
        //                int len = 16;//数据长度   
        //                if (token.Buffer.Count < len) break;//数据不够的时候什么都不做   
        //                token.Buffer.CopyTo(0, binary_data_1, 0, len);//复制一条完整数据到具体的数据缓存   
        //                data_1_catched = true;  //数据判断解析成功
        //                token.Buffer.RemoveRange(0, len);//正确分析一条数据，从缓存中移除数据。   
        //            }
        //            else
        //            {
        //                //这里是很重要的，如果数据开始不是头，则删除数据                      
        //                token.Buffer.RemoveRange(0, token.Buffer.Count);
        //                break;
        //            }
        //            // }
        //            //分析数据   
        //            if (data_1_catched)
        //            {
        //                Listening = true;
        //                data_1_catched = false;
        //                //</协议解析>   
        //                ///////////////////////////////////////////////////////////////////////////////////////////////////////////// 
        //                switch (data[2])
        //                {
        //                    case 0x05:
        //                        objAGVInfo = new AGVInfo()
        //                        {
        //                            IP = token.IPAddress.ToString(), //IP地址
        //                            PreLandNum = (binary_data_1[3] << 8) + binary_data_1[4], //当前地标号
        //                            AimStation = binary_data_1[5],//目标站点
        //                            Speed = binary_data_1[6],//当前速度
        //                            PreAGVStatus = AGVStatus[binary_data_1[7]],//当前AGV状态
        //                            LiftStatus = binary_data_1[8] == 0x0a ? "挂钩升" : "挂钩降", //挂钩状态
        //                            Electricity = (double)binary_data_1[9] + (double)(binary_data_1[10]) / 100,//电量
        //                            UpdateTime = DateTime.Now,//更新时间
        //                            //AGVName = objPreAGV.AGVName,
        //                            //TrackId = objPreAGV.TrackId,
        //                            //TrackName = objPreAGV.TrackName,
        //                            //OnLineStatus = objPreAGV.OnLineStatus
        //                        };
        //                        //根据地标号实现其他功能
        //                        break;
        //                    default:
        //                        objAGVInfo = null;
        //                        break;
        //                }
        //                Listening = false;
        //               // break;
        //            }
        //            else objAGVInfo = null;
        //        }
        //    //}
        //    return objAGVInfo;
        //}
        //#endregion

        #region 协议解析2
        /// <summary>
        /// 调度系统协议解析
        /// </summary>
        /// <param name="data">接收数据</param>
        /// <param name="ip">接收数据的IP地址</param>
        /// <returns>AGV状态信息</returns>
        public AGVInfo ResolutionProtocol2(AsyncUserToken token, byte[] data)
        {
            
            AGVInfo objAGVInfo = null;
            //<协议解析>   
            bool data_1_catched = false;//缓存记录数据是否捕获到   
            //1.缓存数据   
            token.Buffer.AddRange(data);
            //if (Listening == false)
            //{
            //2.完整性判断   
            while (data.Length >= 16)//至少要包含头（2字节）+校验（1字节）   
            {
                //2.1 查找数据头 + 数据尾  
                if (data[0] == 0xAB && data[13] == 0xCD)
                {
                    int len = 16;//数据长度   
                    //if (token.Buffer.Count < len) break;//数据不够的时候什么都不做   
                    //token.Buffer.CopyTo(0, binary_data_1, 0, len);//复制一条完整数据到具体的数据缓存   
                    data_1_catched = true;  //数据判断解析成功
                    //token.Buffer.RemoveRange(0, len);//正确分析一条数据，从缓存中移除数据。   
                }
                else
                {
                    ////这里是很重要的，如果数据开始不是头，则删除数据                      
                    //token.Buffer.RemoveRange(0, token.Buffer.Count);
                    break;
                }
                // }
                //分析数据   
                if (data_1_catched)
                {
                    Listening = true;
                    data_1_catched = false;
                    //</协议解析>   
                    ///////////////////////////////////////////////////////////////////////////////////////////////////////////// 
                    switch (data[2])
                    {
                        case 0x05:
                            //语言选择
                            if (languageid == 3) AGVStatus = JP_AGVStatus;
                            else AGVStatus = CN_AGVStatus;
                            objAGVInfo = new AGVInfo()
                            {
                                IP = token.IPAddress.ToString(), //IP地址
                                PreLandNum = (data[3] << 8) + data[4], //当前地标号
                                AimStation = data[5],//目标站点
                                Speed = data[6],//当前速度
                                PreAGVStatus = AGVStatus[data[7]],//当前AGV状态
                                LiftStatus = data[8] == 0x0a ? "↑" : "↓", //挂钩状态
                                Electricity = (double)data[9] + (double)(data[10]) / 100,//电量
                                UpdateTime = DateTime.Now,//更新时间
                                //AGVName = objPreAGV.AGVName,
                                //TrackId = objPreAGV.TrackId,
                                //TrackName = objPreAGV.TrackName,
                                //OnLineStatus = objPreAGV.OnLineStatus
                            };
                            //根据地标号实现其他功能
                            break;
                        default:
                            objAGVInfo = null;
                            break;
                    }
                    Listening = false;
                    break;
                }
                else objAGVInfo = null;
            }
            //}
            return objAGVInfo;
        }
        #endregion

        #region 发送数据
        /// <summary>
        /// 通过IP地址来发送数据
        /// </summary>
        /// <param name="ip"></param>
        /// <param name="dic"></param>
        /// <param name="objOrderList"></param>
        /// <returns></returns>
        public bool SendDataByIP(string ip, Dictionary<string, Socket> dic, OrderList objOrderList)
        { 
            //【1】查找上线列表中是否存在发送AGV的IP的Socket
            Socket objSocket = null;
            string point = "";
            foreach (string key in dic.Keys)
            {
                if (key.Contains(ip))
                {
                    objSocket = dic[key];
                    point = key;
                    break; //退出循环
                }
            }
            //【2】根据是否找到存在的IP发送数据
            if (objSocket == null) return false;
            if (objSocket.Connected == false)
            {
                dic.Remove(point);
                return false;
            }
            Byte[] orderdata = new Byte[10];
            Int32 crc;
            orderdata[0] = 0xAB;
            orderdata[2] = (byte)objOrderList.CMD; //功能码
            orderdata[4] = (byte)(objOrderList.Data >> 8);//高8位
            orderdata[3] = (byte)(objOrderList.Data); //低8位
            orderdata[5] = 0x00;
            orderdata[6] = 0x00;
            orderdata[7] = 0xCD;
            crc = CRC_Check(orderdata, 8);
            orderdata[8] = (byte)(crc >> 8);
            orderdata[9] = (byte)(crc);
            string txtSendData = byteToHexStr(orderdata);
            try
            {
                new SocketHelper.ServerHelper().SocketSendData(objSocket, txtSendData);
                //objSocket.Send(txtSendData);
                return true;
            }
            catch (Exception ex)
            {                
                throw new Exception("手动调试失败。"+ex.Message);
                //dic.Remove(point); //删除掉线AGV
               // return false;
            }
            
        }
        public bool SendDataByIP(AsyncUserToken token,OrderList objOrderList)
        {          
            Byte[] orderdata = new Byte[10];
            Int32 crc;
            orderdata[0] = 0xAB;
            orderdata[2] = (byte)objOrderList.CMD; //功能码
            orderdata[4] = (byte)(objOrderList.Data >> 8);//高8位
            orderdata[3] = (byte)(objOrderList.Data); //低8位
            orderdata[5] = 0x00;
            orderdata[6] = 0x00;
            orderdata[7] = 0xCD;
            crc = CRC_Check(orderdata, 8);
            orderdata[8] = (byte)(crc >> 8);
            orderdata[9] = (byte)(crc);
            string txtSendData = byteToHexStr(orderdata);
            try
            {
                token.Socket.Send(orderdata);
                return true;
            }
            catch (Exception ex)
            {
                throw new Exception("手动调试失败。" + ex.Message);
            }

        }
        /// <summary>
        /// 根据输入的指令转换成16进制发送的数据
        /// </summary>
        /// <param name="objOrderList">指令</param>
        /// <returns></returns>
        public byte[] GetSendData(OrderList objOrderList)
        {
            Byte[] orderdata = new Byte[10];
            Int32 crc;
            orderdata[0] = 0xAB;
            orderdata[2] = (byte)objOrderList.CMD; //功能码
            orderdata[4] = (byte)(objOrderList.Data >> 8);//高8位
            orderdata[3] = (byte)(objOrderList.Data); //低8位
            orderdata[5] = 0x00;
            orderdata[6] = 0x00;
            orderdata[7] = 0xCD;
            crc = CRC_Check(orderdata, 8);
            orderdata[8] = (byte)(crc >> 8);
            orderdata[9] = (byte)(crc);
            return orderdata;
        }
        #endregion

        #region CRC校验
        /// <summary>
        /// CRC校验
        /// </summary>
        /// <param name="cBuffer">输入数组</param>
        /// <param name="iBufLen">数据长度</param>
        /// <returns></returns>
        private Int32 CRC_Check(byte[] cBuffer, Int32 iBufLen)
        {
            Int32 i, j;
            Int32 wCrc = 0xffff;
            Int32 wPolynom = 0x8408;

            for (i = 0; i < iBufLen; i++)
            {
                wCrc ^= cBuffer[i];

                for (j = 0; j < 8; j++)
                {
                    if (Convert.ToBoolean(wCrc & 0x0001))
                    {
                        wCrc = (wCrc >> 1) ^ wPolynom;
                    }
                    else
                    {
                        wCrc = wCrc >> 1;
                    }
                }
            }
            return wCrc;
        }


        /// <summary>
        /// 字节数组转16进制字符串
        /// </summary>
        /// <param name="bytes">需要转换的数组</param>
        /// <returns>返回字符串</returns>
        public  string byteToHexStr(byte[] bytes)
        {
            string returnStr = "";

            if (bytes != null)
            {
                for (int i = 0; i < bytes.Length; i++)
                {
                    returnStr += bytes[i].ToString("X2") + " ";
                }
            }
            return returnStr;
        }
        #endregion

        #region AGV调度算法服务函数
        /// <summary>
        /// AGV调度算法服务函数
        /// </summary>
        /// <param name="objDgv">AGV信息列表datagridview</param>
        /// <param name="objCallDgv">呼叫信息列表datagridview</param>
        /// <param name="dic">在线AGV列表</param>
        /// <param name="listCall">呼叫信息集合</param>
        public List<ExCall> TaskScheduling(DataGridView objDgv,DataGridView objCallDgv,Dictionary<string ,Socket> dic,List<ExCall> listCall)
        {
            
            List<ExCall> list = new List<ExCall>(); //
            //【1】如果AGV列表和呼叫列表都没存在数据，则不执行一下函数
            if (objDgv.Rows.Count != 0 && objCallDgv.Rows.Count != 0)
            {
                //【2】轮那台AGV处于待命状态
                for (int i = 0; i < objDgv.Rows.Count; i++)
                {              
                    //【3】寻找到待命的AGV
                    if (objDgv.Rows[i].Cells["PreAGVStatus"].Value.ToString() == "待命中")
                    {
                        string trackName = objDgv.Rows[i].Cells["TrackName"].Value.ToString();
                        int index =listCall.FindIndex(s => s.TrackName == trackName);
                        if (index != -1)
                        {
                            string ip = objDgv.Rows[i].Cells["IP"].Value.ToString();
                            /*-------------------------------发送第一个站点-------------------------------*/
                            OrderList objOrderList = new OrderList() { CMD = 6 };
                            int station1 = listCall[index].Station1;
                            if (station1 != 0)
                            {
                                objOrderList.Data = station1;
                                SendDataByIP(ip, dic, objOrderList);//发送数据
                            }
                            /*-------------------------------发送第二个站点-------------------------------*/
                            int station2 = listCall[index].Station2;
                            if (station2 != 0)
                            {
                                Thread.Sleep(500);
                                objOrderList.Data = station2;
                                SendDataByIP(ip, dic, objOrderList);//发送数据
                            }
                            /*--------------------------------发送启动信息--------------------------------*/
                            Thread.Sleep(500);
                            objOrderList.CMD = 1;
                            objOrderList.Data = 0x03; //保持原来方向启动
                            SendDataByIP(ip, dic, objOrderList);//发送数据 
                            //添加已经发送的数据
                            list.Add(new ExCall()
                            {
                                TrackName = listCall[index].TrackName,
                                TrackId = listCall[index].TrackId,
                                Station1 = listCall[index].Station1,
                                Station2 = listCall[index].Station2,
                                Station3 = listCall[index].Station3,
                                StartTime = listCall[index].StartTime,
                                FinishTime = DateTime.Now,
                                AGVName = objDgv.Rows[i].Cells["AGVName"].Value.ToString(),
                                IP = listCall[index].IP,
                                RemoteName = listCall[index].RemoteName,
                                PortName = listCall[index].PortName
                            });
                           // 数据库删除已发送信息
                            new RemoteIOManager().DeleteUnfinishCall(listCall[index]);
                            //移除已发送的站点信息
                            listCall.RemoveAt(index);
                            //每派完一次呼叫，呼叫列表就删除一条
                            objCallDgv.Invoke(new Action<List<ExCall>>((s) =>
                            {
                                objCallDgv.DataSource = null;
                                objCallDgv.DataSource = s;
                            }), listCall);                               
                        }                       
                    }
                }
            }
            return list;
        }
        #endregion

        #region AGV调度算法服务函数2
        /// <summary>
        /// AGV调度算法服务函数2
        /// </summary>
        /// <param name="objDgv">AGV信息列表datagridview</param>
        /// <param name="objCallDgv">呼叫信息列表datagridview</param>
        /// <param name="dic">在线AGV列表</param>
        /// <param name="listCall">呼叫信息集合</param>
        public List<ExCall> TaskScheduling(DataGridView objDgv, SocketManager dic, List<ExCall> listCall)
        {
            List<ExCall> list = new List<ExCall>(); //
            //【1】如果AGV列表和呼叫列表都没存在数据，则不执行一下函数
            if (objDgv.Rows.Count != 0 && listCall.Count != 0)
            {
                //【2】轮那台AGV处于待命状态
                for (int i = 0; i < objDgv.Rows.Count; i++)
                {
                    //【3】寻找到待命的AGV
                    if (objDgv.Rows[i].Cells["PreAGVStatus"].Value.ToString() == "待命中" || objDgv.Rows[i].Cells["PreAGVStatus"].Value.ToString() == "待機中")
                    {
                        string trackName = objDgv.Rows[i].Cells["TrackName"].Value.ToString();
                        int index = listCall.FindIndex(s => s.TrackName == trackName);
                        if (index != -1)
                        {
                            string ip = objDgv.Rows[i].Cells["IP"].Value.ToString();
                            AsyncUserToken objAsyncUserToken = dic.ClientList.Find(s => s.Remote.ToString().Contains(ip)); //根据IP地址查询Socket变量
                            /*-------------------------------发送第一个站点-------------------------------*/
                            OrderList objOrderList = new OrderList() { CMD = 6 };
                            int station1 = listCall[index].Station1;
                            if (station1 != 0)
                            {
                                objOrderList.Data = station1;
                                
                                if(objAsyncUserToken!= null)dic.SendMessage(objAsyncUserToken, GetSendData(objOrderList)); //发送数据
                                //SendDataByIP(ip, dic, objOrderList);//发送数据
                            }
                            /*-------------------------------发送第二个站点-------------------------------*/
                            int station2 = listCall[index].Station2;
                            if (station2 != 0)
                            {
                                Thread.Sleep(500);
                                objOrderList.Data = station2;
                                if (objAsyncUserToken != null) dic.SendMessage(objAsyncUserToken, GetSendData(objOrderList)); //发送数据
                            }
                            /*--------------------------------发送启动信息--------------------------------*/
                            Thread.Sleep(500);
                            objOrderList.CMD = 1;
                            objOrderList.Data = 0x03;
                            if (objAsyncUserToken != null) dic.SendMessage(objAsyncUserToken, GetSendData(objOrderList)); //发送数据
                            //添加已经发送的数据
                            list.Add(new ExCall()
                            {
                                TrackName = listCall[index].TrackName,
                                TrackId = listCall[index].TrackId,
                                Station1 = listCall[index].Station1,
                                Station2 = listCall[index].Station2,
                                Station3 = listCall[index].Station3,
                                StartTime = listCall[index].StartTime,
                                FinishTime = DateTime.Now,
                                AGVName = objDgv.Rows[i].Cells["AGVName"].Value.ToString(),
                                IP = listCall[index].IP,
                                RemoteName = listCall[index].RemoteName,
                                PortName = listCall[index].PortName
                            });
                            // 数据库删除已发送信息
                            new RemoteIOManager().DeleteUnfinishCall(listCall[index]);
                            //移除已发送的站点信息
                            listCall.RemoveAt(index);
                            
                        }
                    }
                }
            }
            return list;
        }
        #endregion

        #region 获取异常AGV
        /// <summary>
        /// 获取异常AGV
        /// </summary>
        /// <param name="agvStatus">agv当前状态</param>
        /// <returns>TRUE:异常 false:正常</returns>
        public bool GetAlarmFlag(string agvStatus,string onlineStatus)
        {
            //语言选择
            if (languageid == 3) AGVStatus = JP_AGVStatus;
            else AGVStatus = CN_AGVStatus;
            if ((agvStatus == AGVStatus[0] || agvStatus == AGVStatus[3] || agvStatus == AGVStatus[6] || agvStatus == AGVStatus[7] ||
                agvStatus == AGVStatus[12] || agvStatus == AGVStatus[13] || agvStatus == AGVStatus[29]) && onlineStatus == "在线")
            {
                return true;
            }
            return false;
        }
        public bool SendRemoteIOByIP(SocketManager token, string ip,bool isAlarm)
        {
            foreach (AsyncUserToken item in token.ClientList)
            {
                if (item.IPAddress.ToString() == ip)
                {
                    try
                    {
                        if (isAlarm)
                        {
                            byte[] txd1 = new byte[] { 0x01, 0x05, 0x00, 0x12, 0xff, 0x00, 0x2c, 0x3f };
                            token.SendMessage(item, txd1);
                            byte[] txd2 = new byte[] { 0x01, 0x05, 0x00, 0x10, 0x00, 0x00, 0xcc, 0x0f };
                            token.SendMessage(item, txd2);
                        }
                        else
                        {
                            byte[] txd1 = new byte[] { 0x01, 0x05, 0x00, 0x12, 0x00, 0x00, 0x6d, 0xcf };
                            token.SendMessage(item, txd1);
                            byte[] txd2 = new byte[] { 0x01, 0x05, 0x00, 0x10, 0xff, 0x00, 0x8d, 0xff };
                            token.SendMessage(item, txd2);
                        }
                        return true;
                    }
                    catch (Exception)
                    {                       
                        return false ;
                    }                   
                }
            }
            return false;
        }
        #endregion

    }
}
